/******************************************************************************
*  author: hnuweiwei@gmail.com
*  version: 1.0
*  file: myStack4.h
*  date: 2014.05.25
*  description: 栈的头文件声明
*  other: 定义缺省模板实参，模板参数可以是类型，也可以是普通值，使用数组来实现
          对于非类型的模板参数，不能使用浮点数，class类型的对象或者内部链接对象（String）
******************************************************************************/

#ifndef MYSTACK4_H_INCLUDED
#define MYSTACK4_H_INCLUDED
#include <stdexcept>

template <typename T, int MAXSIZE>
class MyStack {
  private:
    T elems[MAXSIZE];        // elements
    int numElems;            // current number of elements

  public:
    MyStack();                  // constructor
    void push(T const&);      // push element
    void pop();               // pop element
    T top() const;            // return top element
    bool empty() const {      // return whether the stack is empty
        return numElems == 0;
    }
    bool full() const {       // return whether the stack is full
        return numElems == MAXSIZE;
    }
};


// constructor
template <typename T, int MAXSIZE>
MyStack<T,MAXSIZE>::MyStack ()
  : numElems(0)               // start with no elements
{
    // nothing else to do
}

template <typename T, int MAXSIZE>
void MyStack<T,MAXSIZE>::push (T const& elem)
{
    if (numElems == MAXSIZE) {
        throw std::out_of_range("MyStack<>::push(): stack is full");
    }
    elems[numElems] = elem;   // append element
    ++numElems;               // increment number of elements
}

template<typename T, int MAXSIZE>
void MyStack<T,MAXSIZE>::pop ()
{
    if (numElems <= 0) {
        throw std::out_of_range("MyStack<>::pop(): empty stack");
    }
    --numElems;               // decrement number of elements
}

template <typename T, int MAXSIZE>
T MyStack<T,MAXSIZE>::top () const
{
    if (numElems <= 0) {
        throw std::out_of_range("Stack<>::top(): empty stack");
    }
    return elems[numElems-1];  // return last element
}



#endif // MYSTACK4_H_INCLUDED


//#include<iostream>
//#include "myStack4.h"
//#include <string>
//#include <cstdlib>
//using namespace std;

//int main()
//{
//      try {
//        MyStack<int,20>         int20Stack;     // stack of up to 20 ints
//        MyStack<int,40>         int40Stack;     // stack of up to 40 ints
//        MyStack<std::string,40> stringStack;    // stack of up to 40 strings
//
//        // manipulate stack of up to 20 ints
//        int20Stack.push(7);
//        std::cout << int20Stack.top() << std::endl;
//        int20Stack.pop();
//
//        // manipulate stack of up to 40 strings
//        stringStack.push("hello");
//        std::cout << stringStack.top() << std::endl;
//        stringStack.pop();
//        stringStack.pop();
//    }
//    catch (std::exception const& ex) {
//        std::cerr << "Exception: " << ex.what() << std::endl;
//        return EXIT_FAILURE;  // exit program with ERROR status
//    }
//}
